package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

// sql注入

var db *sqlx.DB // 一个连接池对象

func initDB() (err error) {
	dsn := "root:123456@tcp(10.10.10.101:33306)/test_demo"
	db, err = sqlx.Connect("mysql", dsn)
	if err != nil { // dsn格式不正确
		fmt.Printf("dsn: %s invalid, err: %v\n", dsn, err)
		return
	}
	err = db.Ping()
	if err != nil { // 连接不上数据库,说明用户名密码错误
		fmt.Printf("open %s failed, err: %v\n", dsn, err)
		return
	}
	// 设置数据库连接池最大连接数
	db.SetMaxOpenConns(10)
	// 最大闲置连接数
	db.SetMaxIdleConns(5)
	return
}

type user struct {
	Id   int
	Name string
	Age  int
}

// sql注入示例
func sqlInject(name string) {
	// 拼接sql
	//sqlStr := fmt.Sprintf("select id,name,age from user where name = '%s' ", name)
	sqlStr := `select id,name,age from user where id = ?`
	fmt.Printf("SQL: %s\n", sqlStr)

	var users []user
	err := db.Select(&users, sqlStr, name)
	if err != nil {
		fmt.Printf("exec failed, err:%v\n", err)
		return
	}
	for _, v := range users {
		fmt.Println(v)
	}

}

func main() {
	err := initDB()
	if err != nil {
		fmt.Printf("init DB failed, err: %v\n", err)
		return
	}
	fmt.Println("连接数据库成功")

	// sql注入
	//sqlInject("二狗")         // 正常情况
	sqlInject("xxx' or 1=1 #") // sql注入, 直接获取所有结果

	//	所以要用占位符
}
